﻿//using DBUtil.Annotations;
//using DBUtil.Util;
//using System;
//using System.Collections.Generic;
//using System.Data;
//using System.Linq;
//using System.Linq.Expressions;
//using System.Reflection;
//using System.Text;

//namespace DBUtil.Builders
//{
//    /// <summary>
//    /// 默认的更新过滤器
//    /// </summary>
//    /// <typeparam name="T"></typeparam>
//    public class DefaultUpdateBuilder<T> : IUpdateBuilder<T> where T : class, new()
//    {
//        private T _data = null;
//        private List<PropertyInfo> _props = null;
//        private Type _type = null;
//        private string _table = null;
//        private List<(string type, object data)> _commands = new List<(string type, object data)>();
//        private bool _hasBuild = false;
//        private readonly DBAccess db;
//        private string _alias = null;
//        private IWhereBuilder<T> _whereBuilder = null;
//        private (string tableName, Dictionary<string, object> dic, string filterSql, IDataParameter[] paras) _buildDatas;

//        /// <summary>
//        /// 根据DBAccess创建构建器实例
//        /// </summary>
//        /// <param name="db"></param>
//        /// <param name="isUpdateByKey"></param>
//        public DefaultUpdateBuilder(DBAccess db, bool isUpdateByKey)
//        {
//            this.db = db;
//            _type = typeof(T);
//            _props = _type.GetProperties().ToList();
//            _initWhereBuilder();
//            if (isUpdateByKey) _whereBuilder.WhereKey();
//        }

//        /// <summary>
//        /// 给当前操作表设置别名
//        /// </summary>
//        /// <param name="alias"></param>
//        /// <returns></returns>
//        public IUpdateBuilder<T> As(string alias = "t")
//        {
//            _alias = alias;
//            return this;
//        }

//        /// <summary>
//        /// 忽略指定的属性
//        /// </summary>
//        /// <param name="expression"></param>
//        /// <returns></returns>
//        public IUpdateBuilder<T> Ignore(Expression<Func<T, object>> expression)
//        {
//            _commands.Add((nameof(Ignore), expression));
//            return this;
//        }

//        /// <summary>
//        /// 忽略所有的属性
//        /// </summary>
//        /// <returns></returns>
//        public IUpdateBuilder<T> IgnoreAll()
//        {
//            _commands.Add((nameof(IgnoreAll), null));
//            return this;
//        }

//        /// <summary>
//        /// 表示Set语法,将指定的一个或多个属性映射到Set字句中
//        /// </summary>
//        /// <param name="expression"></param>
//        /// <returns></returns>
//        public IUpdateBuilder<T> Set(Expression<Func<T, object>> expression)
//        {
//            _commands.Add((nameof(Set), expression));
//            return this;
//        }

//        /// <summary>
//        /// 表示Set语法,将指定的一个或多个属性映射到Set字句中,并且将列值直接拼接到Sql语句中
//        /// </summary>
//        /// <param name="expression"></param>
//        /// <returns></returns>
//        public IUpdateBuilder<T> SetRaw(Expression<Func<T, object>> expression)
//        {
//            _commands.Add((nameof(SetRaw), expression));
//            return this;
//        }

//        /// <summary>
//        /// 执行更新返回受影响的行数
//        /// </summary>
//        /// <returns></returns>
//        public int Update()
//        {
//            _build();
//            return db.Update(_buildDatas.tableName, _buildDatas.dic, _buildDatas.filterSql, _buildDatas.paras);
//        }

//        /// <summary>
//        /// 执行更新并根据查询构建器重新查询出模型
//        /// </summary>
//        /// <param name="selectBuilder"></param>
//        /// <returns></returns>
//        public T UpdateAndGetModel(ISelectBuilder<T> selectBuilder = null)
//        {
//            throw new NotImplementedException();
//        }

//        /// <summary>
//        /// 执行更新并根据查询构建器重新查询出模型集合
//        /// </summary>
//        /// <param name="selectBuilder"></param>
//        /// <returns></returns>
//        public List<T> UpdateAndGetModels(ISelectBuilder<T> selectBuilder = null)
//        {
//            throw new NotImplementedException();
//        }

//        /// <summary>
//        /// 设置更新的模型数据
//        /// </summary>
//        /// <param name="data"></param>
//        /// <returns></returns>
//        public IUpdateBuilder<T> UseModelData(T data)
//        {
//            _data = data;
//            return this;
//        }

//        /// <summary>
//        /// 返回一个IWhereBuilder构建器
//        /// </summary>
//        /// <param name="expression"></param>
//        /// <returns></returns>
//        public IWhereBuilder<T> Where(Expression<Predicate<T>> expression)
//        {
//            _whereBuilder.And(expression);
//            return _whereBuilder;
//        }

//        private void _initWhereBuilder()
//        {
//            if (_whereBuilder == null)
//            {
//                _whereBuilder = new DefaultWhereBuilder<T>(db, () => _alias, () => _table, () => _data);
//                _whereBuilder.Init(this);
//            }
//        }

//        /// <summary>
//        /// 返回一个空的IWhereBuilder实例
//        /// </summary>
//        /// <returns></returns>
//        public IWhereBuilder<T> Where()
//        {
//            return _whereBuilder;
//        }

//        /// <summary>
//        /// 根据过滤条件创建IWhereBuilder实例
//        /// </summary>
//        /// <param name="filterSql"></param>
//        /// <param name="paras"></param>
//        /// <returns></returns>
//        public IWhereBuilder<T> Where(string filterSql, params IDataParameter[] paras)
//        {
//            _whereBuilder.AndRaw(filterSql, paras);
//            return _whereBuilder;
//        }

//        /// <summary>
//        /// 根据主键去更新(执行这个方法将会清除其他的过滤条件)
//        /// </summary>
//        /// <returns></returns>
//        public IUpdateBuilder<T> WhereKey()
//        {
//            _whereBuilder.WhereKey();
//            return this;
//        }

//        private void _build()
//        {
//            if (_hasBuild) throw new Exception($"不能重复构建{nameof(DefaultUpdateBuilder<T>)}");
//            //检测是否设置了模型数据
//            if (_data == null) throw new Exception("必须传入要操作的数据模型!");
//            //首先获取表名
//            if (string.IsNullOrWhiteSpace(_table))
//            {
//                var attr = _type.GetCustomAttribute<TableAttribute>();
//                if (attr == null || string.IsNullOrWhiteSpace(attr.Name))
//                {
//                    _table = _type.Name;
//                }
//                else
//                {
//                    _table = attr.Name;
//                }
//            }
//            //获取要更新的列名和值
//            var index = _commands.FindLastIndex(c => c.type == nameof(IgnoreAll));
//            //model: 0 按注解,1 强制忽略,2 强制引入,3 强制原生引入
//            var fetchRules = new List<(string propName, int model)>();
//            //初始化提取规则
//            foreach (var prop in _props)
//            {
//                fetchRules.Add((prop.Name, 0));
//            }
//            //按顺序处理命令先合并command
//            for (int i = 0; i < _commands.Count; i++)
//            {
//                var command = _commands[i];
//                if (command.type == nameof(IgnoreAll))
//                {
//                    for (int m = 0; m < fetchRules.Count; m++)
//                    {
//                        var item = fetchRules[m];
//                        fetchRules.RemoveAt(m);
//                        fetchRules.Insert(m, (item.propName, 1));
//                    }
//                }
//                else
//                {
//                    var expression = command.data as Expression<Func<T, object>>;
//                    var names = ExpressionUtil.GetMemberName<T>(expression);
//                    for (int j = 0; j < names.Count; j++)
//                    {
//                        var index2 = fetchRules.FindIndex(item => item.propName == names[j]);
//                        if (index2 >= 0)
//                        {
//                            fetchRules.RemoveAt(index2);
//                        }
//                        var model = 0;
//                        if (command.type == nameof(Ignore))
//                        {
//                            model = 1;
//                        }
//                        else if (command.type == nameof(Set))
//                        {
//                            model = 2;
//                        }
//                        else if (command.type == nameof(SetRaw))
//                        {
//                            model = 3;
//                        }
//                        fetchRules.Add((names[j], model));
//                    }
//                }
//            }
//            //根据合并的命令去从模型中提取数据
//            var _fetchdatas = _fetchDatas(fetchRules);
//            //生成过滤条件
//            var (filterSql, paras) = _whereBuilder.Build();
//            _buildDatas = (_table, _fetchdatas, filterSql, paras);
//            _hasBuild = true;
//        }

//        private Dictionary<string, object> _fetchDatas(List<(string propName, int model)> fetchRules)
//        {
//            Dictionary<string, object> dic = new Dictionary<string, object>();
//            for (int i = 0; i < _props.Count; i++)
//            {
//                var prop = _props[i];
//                var propname = prop.Name;
//                var rule = fetchRules.Find(item => item.propName == propname);
//                //强制忽略
//                if (rule.model == 1) continue;
//                //主键信息
//                var key = prop.GetCustomAttribute<KeyAttribute>();
//                var isKey = key != null;
//                //判断引入的类型:原生引用,参数化引用
//                var isPara = true;
//                if (rule.model == 3)
//                {
//                    isPara = false;
//                }
//                else if (rule.model == 2)
//                {
//                    isPara = true;
//                }
//                else if (rule.model == 0)
//                {
//                    //默认不更新主键
//                    if (isKey) continue;
//                    //跳过 [NotMapped]
//                    var isNotMapper = prop.GetCustomAttribute<NotMappedAttribute>() != null;
//                    if (isNotMapper) continue;
//                    //判断是否使用sql直接拼接
//                    isPara = prop.GetCustomAttribute<RawValueAttribute>() == null;
//                }

//                var (colname, colvalue) = _getPropValue(prop, _data);
//                if (isPara) dic.Add(colname, colvalue);
//                else dic.Add(colname, (colvalue, true));
//            }
//            return dic;
//        }

//        private (string colName, object value) _getPropValue(PropertyInfo prop, object inst)
//        {
//            //获取列名
//            var col = "";
//            var colAttr = prop.GetCustomAttribute<ColumnAttribute>();
//            if (colAttr == null || string.IsNullOrWhiteSpace(colAttr.Name))
//            {
//                col = prop.Name;
//            }
//            else
//            {
//                col = colAttr.Name;
//            }
//            //获取值
//            object value = prop.GetValue(inst);
//            return (col, value);
//        }

//        /// <summary>
//        /// 指定操作的表名
//        /// </summary>
//        /// <param name="tableName"></param>
//        /// <returns></returns>
//        public IUpdateBuilder<T> UseTable(string tableName)
//        {
//            if (!string.IsNullOrWhiteSpace(tableName)) _table = tableName;
//            return this;
//        }
//    }
//}
